import React, { Component } from "react";
import { Card, Button, Tabs } from "antd";
import moment from "moment";
import "./style.scss";
import {nativeLogTypeConfigs, webLogTypeConfigs} from "../../../../../consts/logtypes";
import StackTree from "../../../strack-tree";
import PrismHighlighter from "../../../prism-highlighter";

const titleByKey = {
  "id": "日志编号",
  "taskId": "任务编号",
  "logType": "日志类型",
  "logTime": "日志记录时间",
  "content": "日志内容",
  "extra": "其他信息",
  "modelVersion": "机型",
  "devicePower": "设备电量",
  "batteryTemperature": "电池温度",
  "area": "地域",
  "channel": "渠道信息",
  "cpu": "CPU架构",
  "useTime": "使用时长（s）",
  "runtimeType": "前后台状态",
  "network": "网络类型",
  "deviceSystem": "系统",
  "systemVersion": "系统版本",
  "appPackageName": "App包名",
  "reportTime": "错误发生时间",
  "sdkVersion": "SDK版本号",
  "logId": "日志ID",
};

const { TabPane } = Tabs;

// const treeData = [
//   {
//       title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)",
//       key: "0-0",
//       children: [
//           {
//               title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)",
//               key: "0-0-0",
//               children: [
//                   { title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-0-0" },
//                   { title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-0-1" },
//                   { title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-0-2" },
//               ],
//           },
//           {
//               title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)",
//               key: "0-0-1",
//               children: [{ title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-1-0" }],
//           },
//           {
//               title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)",
//               key: "0-0-2",
//               children: [
//                   { title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-2-0" },
//                   { title: "com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)", key: "0-0-2-1" },
//               ],
//           },
//       ],
//   },
// ];

function callback(key) {
  console.log(key);
}

const split = "----------";

// 将数组转换成Tree组件
function convertToTree(array, parent, index) {
  if (index >= array.length) {
    return index;
  }

  while (index < array.length) {
    var str = array[index];
    var node = {
      title: str.m + split + str.t + "ms",
      key: parent.key + "-" + index,
      children: []
    };
    
    parent.children.push(node);

    index = convertToTree(array, node, index + 1);
  }

  return index;
}

class LogDetailCard extends Component {

  render() {
    const { focusLogId, logDetail } = this.props;
    if (focusLogId === -1) {
      return null;
    } else {
      const { cardTitle, closeButton, metaDatas } = this.conposeSnippetComponents();
      const { code, treeData } = this.prettyLogDetail(logDetail);
      console.log(treeData);

      return (
        <Card
            className="detail-information-container"
            title={cardTitle}
            extra={closeButton}>
          <div className="metadata">
            { metaDatas }
          </div>
          <Tabs defaultActiveKey="1" onChange={callback}>
            <TabPane tab="原始日志" key="1">
              {logDetail && <div className="log-content">
              日志信息:<br/>
              { logDetail["content"] }
              </div>}
            </TabPane>
            <TabPane tab="堆栈信息" key="2">
              <PrismHighlighter
                language={"java"}
                code={code}
                plugins={["line-numbers"]}
              />
            </TabPane>
            <TabPane tab="耗时追踪" key="3">
              <StackTree treeData={treeData}/>
            </TabPane>
          </Tabs>
        </Card>
      );
    }
  }

  handleCloseButtonClicked = () => {
    this.props.updateFocusLogId(-1);
  };

  conposeSnippetComponents = () => {
    const { logDetail, type } = this.props;
    console.log(logDetail);
    const logTypesConfig = type === "web" ? webLogTypeConfigs : nativeLogTypeConfigs;
    if (logDetail !== null) {
      const cardTitle = (
        <header>
          <h1>日志条目详情</h1>
        </header>
      );

      const closeButton = (
        <Button icon="close" shape="circle" size="small" onClick={this.handleCloseButtonClicked}/>
      );

      const metaDatas = Object.keys(logDetail).map(key => {
        if (!Object.keys(titleByKey).includes(key)) {
          return null;
        }
        let value = "";
        if (key === "logType") {
          const config = logTypesConfig.find(config => config.logType === logDetail[key]);
          if (config === undefined) {
            value = "未知日志";
          } else {
            value = config["logTypeName"];
          }
        } else if (key === "logTime") {
          value = moment(logDetail[key]).format('YYYY-MM-DD HH:mm:ss.SSS');
        } else if (key === "content") {
          // const valueTest = "{\"area\": \"\", 	\"channel\": \"\", 	\"deviceId\": \"1aa514e76b2244fbd59b2e3d3c6aa962\", 	\"deviceName\": \"halo\", 	\"deviceOperator\": 0, 	\"deviceSystem\": \"androidApi-32\", 	\"extra\": { 		\"appPackageName\": \"com.example.apm\", 		\"cpu\": \"arm64-v8a,armeabi-v7a,armeabi\", 		\"devicePower\": 0.0, 		\"isForeground\": true, 		\"isRoot\": false, 		\"modelVersion\": \"Lenovo L71091\", 		\"sdkVersion\": \"1.0.3-SNAPSHOT\", 		\"useTime\": 39122 	}, 	\"level\": \"ERROR\", 	\"logId\": \"02d1da58662f209cdcdb1ddfbe9fa4b8\", 	\"message\": \"form self test E\", 	\"page\": \"com.example.apm.MainActivity\", 	\"reportTime\": 1687858336280, 	\"stackTrace\": \"java.lang.RuntimeException: form self test E\\r\\n\\tat com.example.apm.MainActivity$onCreate$4.onClick(MainActivity.kt:37)\\r\\n\\tat android.view.View.performClick(View.java:7455)\\r\\n\\tat android.view.View.performClickInternal(View.java:7432)\\r\\n\\tat android.view.View.access$3700(View.java:835)\\r\\n\\tat android.view.View$PerformClick.run(View.java:28832)\\r\\n\\tat android.os.Handler.handleCallback(Handler.java:938)\\r\\n\\tat android.os.Handler.dispatchMessage(Handler.java:99)\\r\\n\\tat android.os.Looper.loopOnce(Looper.java:225)\\r\\n\\tat android.os.Looper.loop(Looper.java:326)\\r\\n\\tat android.app.ActivityThread.main(ActivityThread.java:8305)\\r\\n\\tat java.lang.reflect.Method.invoke(Native Method)\\r\\n\\tat com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)\\r\\n\\tat com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)\\r\\n\", 	\"threadName\": \"main\", 	\"type\": 1, 	\"version\": \"1.0\" } \"";
          return this.parseLogDetailContent(logDetail, key);
        } else {
          value = logDetail[key];
        }

        return (
          <div className="metadata-item" key={titleByKey[key]}>
            { titleByKey[key] } : { value }
          </div>
        )
      });

      return {
        cardTitle,
        closeButton,
        metaDatas
      }
    } else {
      return {
        cardTitle: null,
        closeButton: null,
        metaDatas: null
      }
    }

  };

  parseLogDetailExtra(content) {
    if (content) {
      return Object.keys(content).map(key => {
        if (!Object.keys(titleByKey).includes(key)) {
          return null;
        }
        let value = "";
        if (key === "isRoot") {
          value = content.isRoot ? "是": "否";
        } else if (key === "useTime") {
          value = (content.useTime / 1000).toFixed(2) + "s";
        } else if (key === "runtimeType") {
          value = content.runtimeType === 1 ? "前台":"后台";
        }  else if (key === "devicePower") {
          value = content.devicePower ? content.devicePower + "%" : "未知";
        } else {
          value = content[key] ? content[key] : "未知";
        }
        return (
          <div className="metadata-item" key={titleByKey[key]}>
            { titleByKey[key] } : { value }
          </div>
        )
      })
    }
    return "";
  }

  parseLogDetailContent(logDetail, key) {
    let content = undefined;
    if (!this.isJSON(logDetail[key])) {
      return "";
    }

    try {
      console.log(logDetail[key]);
      content = JSON.parse(logDetail[key]);
    } catch (error) {
      // 解析失败时的错误处理逻辑
      console.error('Failed to parse JSON:', error);
      return "";
    }
    console.log(content);
    if (content) {
      return Object.keys(content).map(key => {
        if (!Object.keys(titleByKey).includes(key)) {
          return null;
        }
        let value = "";
        if (key === "isRoot") {
          value = content.isRoot ? "是": "否";
        } else if (key === "reportTime") {
          value = moment(logDetail[key]).format('YYYY-MM-DD HH:mm:ss.SSS');
        } else if (key === "extra") {
           return this.parseLogDetailExtra(content.extra);
        } else {
          value = content[key];
        }
        return (
          <div className="metadata-item" key={titleByKey[key]}>
            { titleByKey[key] } : { value }
          </div>
        )
      })
    }
    return "";
  }

  isJSON(str) {
    if (typeof str !== 'string') {
      return false;
    }
  
    try {
      const firstChar = str.trim().charAt(0);
      const lastChar = str.trim().charAt(str.length - 1);
  
      return (firstChar === '{' && lastChar === '}') || (firstChar === '[' && lastChar === ']');
    } catch (e) {
      return false;
    }
  }

  // 解析日志详情
  prettyLogDetail(logDetail) {
    let contentJson = logDetail["content"] ? logDetail["content"] : null;

    let content;
    const treeData = [];
    if (!this.isJSON(contentJson)) {
      const code = null;
      return {code, treeData};
    }
    
    try {
      content = JSON.parse(contentJson);
    } catch (error) {
      // 解析失败时的错误处理逻辑
      console.error('Failed to parse JSON:', error);
      content = null;
    }
    const code = content ? content["stackTrace"] : null;
    //const code = "com.example.apm.MainActivity:test3:()V 1 0\r\ncom.example.apm.MainActivity:test2:(I)V 3 0\r\ncom.example.apm.MainActivity:test2:(I)V 4 0\r\ncom.example.apm.MainActivity:testMethodExecTimeAst1:()V 1 403\r\ncom.example.apm.MainActivity$onCreate$1:onClick:(Landroid.view.View;)V 1 410\r\n";
    const traceProfiler = content["traceProfiler"] ? content["traceProfiler"] : null;
    // const treeDataTest = "[{\"m\":\"com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)\",\"t\":1000,\"r\":1},{\"m\":\"com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)\",\"t\":1000,\"r\":2},{\"m\":\"com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)\",\"t\":1000,\"r\":3},{\"m\":\"com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)\",\"t\":1000,\"r\":4},{\"m\":\"com.meituan.logan.web.service.AppLogStrategyServiceTest.test2(AppLogStrategyServiceTest.java:105)\",\"t\":1000,\"r\":5}]";
    // const treeDataTest = "[{\"execCount\":1,\"m\":\"com.example.apm.Test:getIns1:()V\",\"r\":1,\"t\":0},{\"execCount\":1,\"m\":\"com.example.apm.MainActivity:test3:()V\",\"r\":2,\"t\":0},{\"execCount\":3,\"m\":\"com.example.apm.MainActivity:test2:(I)V\",\"r\":3,\"t\":0},{\"execCount\":4,\"m\":\"com.example.apm.MainActivity:test2:(I)V\",\"r\":4,\"t\":0},{\"execCount\":1,\"m\":\"com.example.apm.MainActivity:testMethodExecTimeAst1:()V\",\"r\":5,\"t\":412},{\"execCount\":1,\"m\":\"com.example.apm.MainActivity$onCreate$1:onClick:(Landroid.view.View;)V\",\"r\":6,\"t\":412}]";
    // const treeData = JSON.parse(treeDataTest);
    if (traceProfiler) {
      const rootNode = {
        'title': traceProfiler[0].m + split + content["duration"] + "ms",
        'key': "0",
        'children': []
      };
      console.log(convertToTree(traceProfiler, rootNode, 1));
      console.log(rootNode);
      treeData.push(rootNode);
    }
    return { code, treeData };
  }
}

export default LogDetailCard;
